Android  MeasureSpec 의 이해 와 소스 코드 분석

13531 단어 AndroidMeasureSpec
Android  MeasureSpec 의 이해 와 소스 코드 분석
MeasureSpec 생 성 규칙:

실례 설명:

package cc.ww; 
 
import android.view.View; 
import android.view.View.MeasureSpec; 
import android.view.ViewGroup.LayoutParams; 
import android.view.ViewGroup.MarginLayoutParams; 
import android.widget.LinearLayout; 
 
/** 
 * @author http://blog.csdn.net/lfdfhl 
 * 
 *     : 
 *   MeasureSpec    
 * 
 * (1) MeasureSpec     
 *   MeasureSpec     "    ",    32  int  . 
 *      2   SpecMode       , 32  SpecSize            . 
 *       :  
 *   int specMode = MeasureSpec.getMode(measureSpec)   specMode 
    int specSize = MeasureSpec.getSize(measureSpec)   SpecSize 
    
         SpecMode   : 
      
    MeasureSpec.EXACTLY 
           
    Measure specification mode: The parent has determined an exact size 
    for the child. The child is going to be given those bounds regardless of how big it wants to be. 
                  View        .  View         SpecSize. 
    (1)   View LayoutParams  ( )      ( 100px)      MeasureSpec  MeasureSpec.EXACTLY   
    MeasureSpec.AT_MOST  MeasureSpec.UNSPECIFIED : 
                View specMode   MeasureSpec.EXACTLY 
                View specSize   View       (childSize) 
              : 
          View LayoutParams  ( )      ( 100px) ,      View         ,        px  
               .          specMode   ,       View specMode  MeasureSpec.EXACTLY,   
                View specSize   View       (childSize). 
    
    (2)   View LayoutParams  ( )  match_parent       MeasureSpec  MeasureSpec.EXACTLY : 
                View specMode   MeasureSpec.EXACTLY 
                View specSize             (parentLeftSize) 
              : 
       View LayoutParams  ( )  match_parent       MeasureSpec  MeasureSpec.EXACTLY. 
            View         :          ,               View    . 
        ,     MeasureSpec  MeasureSpec.EXACTLY  : 
             View specMode   MeasureSpec.EXACTLY,      . 
                View specSize             (parentLeftSize),          . 
                  ,MeasureSpec  MeasureSpec.AT_MOST ? 
                View specMode   MeasureSpec.AT_MOST,      . 
                View specSize             (parentLeftSize),          . 
      
    MeasureSpec.AT_MOST 
           
    The child can be as large as it wants up to the specified size. 
                   specSize, View         . 
    (1)   View LayoutParams  ( )  match_parent       MeasureSpec  MeasureSpec.AT_MOST : 
                View specMode   MeasureSpec.AT_MOST 
                View specSize             (parentLeftSize) 
                     MeasureSpec.EXACTLY       . 
   (2)   View LayoutParams  ( )  wrap_content       MeasureSpec  MeasureSpec.EXACTLY : 
                View specMode   MeasureSpec.AT_MOST 
                View specSize             (parentLeftSize) 
              : 
          View LayoutParams  ( )  wrap_content      View      ,  content  . 
                   MeasureSpec  MeasureSpec.EXACTLY           ;         
          View     ,       ,   
                View specMode          MeasureSpec.AT_MOST 
                View specSize             (parentLeftSize) 
    (3)   View LayoutParams  ( )  wrap_content       MeasureSpec  MeasureSpec.AT_MOST : 
                View specMode   MeasureSpec.AT_MOST 
                View specSize             (parentLeftSize) 
              : 
          View LayoutParams  ( )  wrap_content      View      ,  content  . 
                   MeasureSpec  MeasureSpec.AT_MOST         
          View     ,         ,   
                View specMode          MeasureSpec.AT_MOST 
                View specSize             (parentLeftSize) 
         
    
    MeasureSpec.UNSPECIFIED 
           
    The parent has not imposed any constraint on the child. It can be whatever size it wants. 
            View      . 
          Android    ,  ListView ScrollView.      . 
      
                              ,        . 
    
 * (2)  onMeasure()  View MeasureSpec        
 *            ,         . 
 * 
 */ 
public class UnderstandMeasureSpec { 
   
  /** 
   *    : 
   *  ViewGroup   View     measureChildWithMargins()  ,         . 
   *         : 
   * @param child 
   *  View 
   * @param parentWidthMeasureSpec 
   *    (  LinearLayout)   MeasureSpec 
   * @param widthUsed 
   *    (  LinearLayout)               
   * @param parentHeightMeasureSpec 
   *    (  LinearLayout)   MeasureSpec 
   * @param heightUsed 
   *    (  LinearLayout)               
   * 
   *             ,          getChildMeasureSpec()      
   *  View MeasureSpec.         
   */ 
  protected void measureChildWithMargins(View child,int parentWidthMeasureSpec, int widthUsed, 
                           int parentHeightMeasureSpec, int heightUsed) { 
    //1    View LayoutParams 
    final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 
    //2    View   MeasureSpec 
    final int childWidthMeasureSpec = getChildMeasureSpec 
    (parentWidthMeasureSpec,mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin + widthUsed, lp.width); 
    //3    View   MeasureSpec 
    final int childHeightMeasureSpec = getChildMeasureSpec 
    (parentHeightMeasureSpec,mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin + heightUsed, lp.height); 
    //4    View 
    child.measure(childWidthMeasureSpec, childHeightMeasureSpec); 
  } 
   
   
  /** 
   * getChildMeasureSpec()     View MeasureSpec 
   *         : 
   * @param spec 
   *    (  LinearLayout)     MeasureSpec 
   * @param padding 
   *    (  LinearLayout)                  . 
   *  measureChildWithMargins()     getChildMeasureSpec()           : 
   *   :mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin 
   *   : 
   * mPaddingLeft mPaddingRight           padding 
   * lp.leftMargin lp.rightMargin   View      margin 
   *                 View.          : 
   *                  
   *   : 
   * mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin 
   *   : 
   *    (  LinearLayout)            . 
   * @param childDimension 
   *    View LayoutParams     View     
   * 
   * 
   *         getChildMeasureSpec()                      : 
   *    ( LinearLayout) MeasureSpec  View LayoutParams      View MeasureSpec!!! 
   * 
   * 
   * 
   */ 
   public static int getChildMeasureSpec(int spec, int padding, int childDimension) { 
      /** 
       *    :      specMode specSize 
       */ 
      int specMode = MeasureSpec.getMode(spec); 
      int specSize = MeasureSpec.getSize(spec); 
      /** 
       *    :                       . 
       *      padding        
       */ 
      int size = Math.max(0, specSize - padding); 
 
      int resultSize = 0; 
      int resultMode = 0; 
 
       
      /** 
       *    :   View specMode specSize. 
       *              . 
       */ 
      switch (specMode) { 
      /** 
       *      : 
       *          EXACTLY 
       * 
       *          : 
       * LayoutParams.MATCH_PARENT=-1 
       * LayoutParams.WRAP_CONTENT=-2 
       *         : 
       * childDimension >= 0    View      MATCH_PARENT WRAP_CONTENT 
       */ 
      case MeasureSpec.EXACTLY: 
        /** 
         *           EXACTLY   : 
         *  View           ,  100px; 
         *   : 
         *  View size  childDimension 
         *  View mode  MeasureSpec.EXACTLY 
         */ 
        if (childDimension >= 0) { 
          resultSize = childDimension; 
          resultMode = MeasureSpec.EXACTLY; 
        /** 
         *           EXACTLY   : 
         *  View     LayoutParams.MATCH_PARENT 
         *   : 
         *  View size                        size 
         *  View mode  MeasureSpec.EXACTLY 
         */ 
        } else if (childDimension == LayoutParams.MATCH_PARENT) { 
          // Child wants to be our size. So be it. 
          resultSize = size; 
          resultMode = MeasureSpec.EXACTLY; 
        /** 
         *           EXACTLY   : 
         *  View     LayoutParams.WRAP_CONTENT 
         *   : 
         *  View size                        size 
         *  View mode MeasureSpec.AT_MOST 
         */ 
        } else if (childDimension == LayoutParams.WRAP_CONTENT) { 
          // Child wants to determine its own size. It can't be bigger than us. 
          resultSize = size; 
          resultMode = MeasureSpec.AT_MOST; 
        } 
        break; 
 
      /** 
       *      : 
       *          AT_MOST 
       * 
       *          :pp 
       * LayoutParams.MATCH_PARENT=-1 
       * LayoutParams.WRAP_CONTENT=-2 
       *         : 
       * childDimension >= 0    View      MATCH_PARENT WRAP_CONTENT 
       */ 
      case MeasureSpec.AT_MOST: 
        /** 
         *           AT_MOST   : 
         *  View           ,  100px; 
         *   : 
         *  View size  childDimension 
         *  View mode  MeasureSpec.EXACTLY 
         */ 
        if (childDimension >= 0) { 
          // Child wants a specific size... so be it 
          resultSize = childDimension; 
          resultMode = MeasureSpec.EXACTLY; 
        /** 
         *           AT_MOST   : 
         *  View     LayoutParams.MATCH_PARENT 
         *   : 
         *  View size                        size 
         *  View mode  MeasureSpec.AT_MOST 
         */ 
        } else if (childDimension == LayoutParams.MATCH_PARENT) { 
          // Child wants to be our size, but our size is not fixed. 
          // Constrain child to not be bigger than us. 
          resultSize = size; 
          resultMode = MeasureSpec.AT_MOST; 
         /** 
         *           AT_MOST   : 
         *  View     LayoutParams.WRAP_CONTENT 
         *   : 
         *  View size                        size 
         *  View mode  MeasureSpec.AT_MOST 
         */ 
        } else if (childDimension == LayoutParams.WRAP_CONTENT) { 
          // Child wants to determine its own size. It can't be 
          // bigger than us. 
          resultSize = size; 
          resultMode = MeasureSpec.AT_MOST; 
        } 
        break; 
 
      /** 
       *      : 
       *          UNSPECIFIED 
       * 
       *          : 
       * LayoutParams.MATCH_PARENT=-1 
       * LayoutParams.WRAP_CONTENT=-2 
       *         : 
       * childDimension >= 0    View      MATCH_PARENT WRAP_CONTENT 
       */ 
      case MeasureSpec.UNSPECIFIED: 
        /** 
         *           UNSPECIFIED   : 
         *  View           ,  100px; 
         *   : 
         *  View size  childDimension 
         *  View mode  MeasureSpec.EXACTLY 
         */ 
        if (childDimension >= 0) { 
          // Child wants a specific size... let him have it 
          resultSize = childDimension; 
          resultMode = MeasureSpec.EXACTLY; 
        /** 
         *           UNSPECIFIED   : 
         *  View     LayoutParams.MATCH_PARENT 
         *   : 
         *  View size 0 
         *  View mode  MeasureSpec.UNSPECIFIED 
         */ 
        } else if (childDimension == LayoutParams.MATCH_PARENT) { 
          // Child wants to be our size... find out how big it should be 
          resultSize = 0; 
          resultMode = MeasureSpec.UNSPECIFIED; 
        /** 
         *           UNSPECIFIED   : 
         *  View     LayoutParams.WRAP_CONTENT 
         *   : 
         *  View size 0 
         *  View mode  MeasureSpec.UNSPECIFIED 
         */ 
        } else if (childDimension == LayoutParams.WRAP_CONTENT) { 
          // Child wants to determine its own size.... find out how big it should be 
          resultSize = 0; 
          resultMode = MeasureSpec.UNSPECIFIED; 
        } 
        break; 
      } 
      return MeasureSpec.makeMeasureSpec(resultSize, resultMode); 
    } 
   
   
 
} 




 궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 의 커 뮤 니 티 에 가서 토론 을 교류 하 세 요.읽 어 주 셔 서 감사합니다. 도움 이 되 셨 으 면 좋 겠 습 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기